/**
* @file test-pipe.c
* Betriebssysteme Beispiel 2 - test-pipe
*
* @author Christian Lachner <ic11b010@technikum-wien.at>
* @author Max Paflik <ic11b006@technikum-wien.at>
* @date 2012/04/20
*
* @version $Revision: 004 $
*
* URL: $HeadURL$
*
* Last Modified: $Author: Chris $
*/

#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "mypoc.h"

#define MAX_CMDBUF 255
/* windows uses 2 chars for \n, unix only 1 */
#ifdef __unix__
	#define MAX_TYPEBUF 2
#else
	#define MAX_TYPEBUF 3
#endif
#define MAX_RXTXBUF 255


void print_usage();
void print_error_eno(int eno);
void print_error_msg(char * msg);

static const char * thisfname;

/**
*
* prints Prints usage-information.
*
* \return void
*/
void print_usage() {
	printf("\nUsage: %s\n\n", thisfname);
}

/**
*
* \brief Elaborates errormessages by eno and calls print_error_msg
*
* \param eno The error-number that which's message-string is being generated.
*
* \return void
*/
void print_error_eno(int eno) {
	print_error_msg(strerror(eno));
}

/**
*
* \brief Prints error messages in a standardized format
*
* \param msg The message that is being printed.
*
* \return void
*/
void print_error_msg(char * msg) {
	fprintf(stderr, "%s: %s\n", thisfname, msg);
}

/**
*
* \brief Simple pipe-test-program to test popen and pclose implementations.
*
* \param argc the number of arguments
* \param argv the arguments itselves (including the program name in argv[0])
*
* \return success or failure
*/
int main(int argc, char * argv[]) {
	char cmd[MAX_CMDBUF];		/* char-array that holds the command-string */
	char type[MAX_TYPEBUF];		/* char-array that holds the type-string. only first char will be used later. */
	char rxtxbuf[MAX_RXTXBUF];	/* char-array that functions as a buffer for RX and TX for pipe operations. */
	int charcount = 0;			/* counts read or written amount of characters */
	int tmp = 0;
	FILE * fp_pipe = NULL;		/* filepointer for pipe */

	/* set the filename of the called binary */
	thisfname = argv[0];

	/* handle illegal parameter counts */
	if(argc != 1) {
		print_usage();
		exit(EXIT_SUCCESS);
	}

	/* collect command information */
	if(printf("Command> ") <= 0) {
		if(errno != 0) {
			print_error_eno(errno);
		} else {
			print_error_msg("General printf malfunction");
		}
		exit(EXIT_FAILURE);
	}

	fgets(cmd, MAX_CMDBUF, stdin);
	if(cmd == NULL) {
		if(errno != 0) {
			print_error_eno(errno);
		} else {
			print_error_msg("General fgets malfunction");
		}
	}

	errno = 0;
	if(sscanf(cmd, "%[ ]s", cmd) < 0) {
		if(errno != 0) {
			print_error_eno(errno);
		} else {
			print_error_msg("sscanf() for command failed!\n");
		}
	}

	/* collect type information */
	if(printf("Type (r/w)> ") <= 0) {
		if(errno != 0) {
			print_error_eno(errno);
		} else {
			print_error_msg("General printf malfunction");
		}
		exit(EXIT_FAILURE);
	}

	fgets(type, MAX_TYPEBUF, stdin);
	if(type == NULL) {
		if(errno != 0) {
			print_error_eno(errno);
		} else {
			
		}
	}

	errno = 0;
	if(sscanf(type, "%s", type) < 0) {
		if(errno != 0) {
			print_error_eno(errno);
		} else {
			print_error_msg("sscanf() for command failed!\n");
		}
	}

	/* create pipe and do what the user told you to do */
	if(type[0] == 'r' || type[0] == 'R') {
		if((fp_pipe = mypopen(cmd, "r")) == NULL) {
			print_error_eno(errno);
			exit(EXIT_FAILURE);
		}

		while(fgets(rxtxbuf, MAX_RXTXBUF, fp_pipe) != NULL) {
			tmp = fprintf(stdout, "%s", rxtxbuf);
			if(tmp < 0) {
				print_error_eno(errno);
			}
			charcount += tmp;
		}
		printf("\n %d characters read.\n\n", charcount);
	} else if(type[0] == 'w' || type[0] == 'W') {
		if((fp_pipe = mypopen(cmd, "w")) == NULL) {
			print_error_eno(errno);
			exit(EXIT_FAILURE);
		}

		while(fgets(rxtxbuf, MAX_RXTXBUF, stdin) != NULL) {
			tmp = fprintf(fp_pipe, "%s", rxtxbuf);
			if(tmp < 0) {
				print_error_eno(errno);
			}
			charcount += tmp;
			fflush(fp_pipe);
		}
		printf("\n %d characters written.\n\n", charcount);
	} else {
		print_error_msg("Invalid type given!");
		exit(EXIT_FAILURE);
	}

	if(mypclose(fp_pipe) == -1) {
		print_error_msg("pclose() failed somehow!");
		exit(EXIT_FAILURE);
	}

	errno = 0;
	if(fflush(stdout) != EOF) {
		exit(EXIT_SUCCESS);
	} else {
		fprintf(stderr, "Buffer not completely written!\n");
		print_error_eno(errno);
		exit(EXIT_FAILURE);
	}
}
